<script setup>
import appStore from "@/stores"
import { ref, onMounted, onUnmounted, watch } from "vue"
import Button from "./Button.vue"

const isPlaying = ref(false)
const currentTime = ref(0)
const duration = ref(0)
const audioRef = ref(null)
const currentSongIndex = ref(0)
const isLoading = ref(false)
const error = ref(null)
const isLoop = ref(false)
const showList = ref(false)
const { songs } = defineProps({
  songs: {
    type: Object,
    required: true,
  },
})
const currentSong = ref({
  id: 1,
  name: "青花瓷",
  artist: "周杰伦",
  fileName: "青花瓷.mp3",
  cover: "https://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg",
})
const { switchTipStatus } = appStore.homeviewStore

const togglePlay = async () => {
  if (!audioRef.value) return
  try {
    if (isPlaying.value) {
      audioRef.value.pause()
      isPlaying.value = false
    } else {
      isLoading.value = true
      error.value = null
      await audioRef.value.play()
      isPlaying.value = true
    }
  } catch (err) {
    error.value = "播放失败，请检查音频文件"
    switchTipStatus({
      level: "warning",
      msg: error.value,
    })
  } finally {
    isLoading.value = false
  }
}

const nextSong = () => {
  currentSongIndex.value = (currentSongIndex.value + 1) % songs.length
  currentSong.value = songs[currentSongIndex.value]
}

const prevSong = () => {
  currentSongIndex.value =
    currentSongIndex.value === 0 ? songs.length - 1 : currentSongIndex.value - 1
  currentSong.value = songs[currentSongIndex.value]
}

// 切歌后自动播放
watch(
  () => currentSong.value.id,
  () => {
    setTimeout(() => {
      togglePlay()
    }, 1000)
  }
)

const updateTime = () => {
  if (audioRef.value) {
    currentTime.value = audioRef.value.currentTime
    duration.value = audioRef.value.duration
  }
}

const seek = (event) => {
  if (!audioRef.value || !duration.value) return
  const rect = event.target.getBoundingClientRect()
  const percent = (event.clientX - rect.left) / rect.width
  // 确保 percent 在 0~1 之间
  const seekTime = Math.max(0, Math.min(percent, 1)) * duration.value
  audioRef.value.currentTime = seekTime
}

const formatTime = (time) => {
  if (isNaN(time)) return "0:00"
  const minutes = Math.floor(time / 60)
  const seconds = Math.floor(time % 60)
  return `${minutes}:${seconds.toString().padStart(2, "0")}`
}

const handleAudioError = () => {
  error.value = "音频加载失败"
  isPlaying.value = false
  isLoading.value = false
}

const handleAudioLoadStart = () => {
  isLoading.value = true
  error.value = null
}

const handleAudioCanPlay = () => {
  isLoading.value = false
  error.value = null
}

const toggleLoop = () => {
  isLoop.value = !isLoop.value
  if (audioRef.value) audioRef.value.loop = isLoop.value
}

const toggleList = () => {
  showList.value = !showList.value
}

const selectSong = (idx) => {
  currentSongIndex.value = idx
  currentSong.value = songs[idx]
  showList.value = false
}

onMounted(() => {
  if (audioRef.value) {
    audioRef.value.addEventListener("timeupdate", updateTime, { passive: true })
    audioRef.value.addEventListener("ended", nextSong, { passive: true })
    audioRef.value.addEventListener("error", handleAudioError, { passive: true })
    audioRef.value.addEventListener("loadstart", handleAudioLoadStart, { passive: true })
    audioRef.value.addEventListener("canplay", handleAudioCanPlay, { passive: true })
    audioRef.value.loop = isLoop.value
  }
})

onUnmounted(() => {
  if (audioRef.value) {
    audioRef.value.pause()
    audioRef.value.currentTime = 0
    isPlaying.value = false
    audioRef.value.removeEventListener("timeupdate", updateTime, { passive: true })
    audioRef.value.removeEventListener("ended", nextSong, { passive: true })
    audioRef.value.removeEventListener("error", handleAudioError, { passive: true })
    audioRef.value.removeEventListener("loadstart", handleAudioLoadStart, { passive: true })
    audioRef.value.removeEventListener("canplay", handleAudioCanPlay, { passive: true })
    audioRef.value.src = ""
  }
})
</script>

<template>
  <div class="music-player-box" :class="{ show: showList }">
    <div class="music-cover">
      <img :src="currentSong.cover" :alt="currentSong.name" />
    </div>
    <div class="music-info-panel">
      <div class="music-title" :title="currentSong.name">{{ currentSong.name }}</div>
      <div class="music-artist" :title="currentSong.artist">{{ currentSong.artist }}</div>
      <div class="music-info-bottom">
        <div class="progress-row">
          <span class="time">{{ formatTime(currentTime) }}</span>
          <div class="progress-bar" @click="seek">
            <div
              class="progress-fill"
              :style="{ width: duration ? (currentTime / duration) * 100 + '%' : '0%' }"></div>
          </div>
          <span class="time">{{ formatTime(duration) }}</span>
          <div class="controls-row">
            <button class="icon-btn" @click="prevSong" :title="'上一首'">
              <i class="fas fa-step-backward"></i>
            </button>
            <Button
              :title="isPlaying ? '暂停' : '播放'"
              :icon="
                isLoading ? 'fas fa-spinner fa-spin' : isPlaying ? 'fas fa-pause' : 'fas fa-play'
              "
              @click-it="togglePlay"></Button>
            <button class="icon-btn" @click="nextSong" :title="'下一首'">
              <i class="fas fa-step-forward"></i>
            </button>
            <button
              class="icon-btn"
              @click="toggleLoop"
              :title="isLoop ? '单曲循环(已开)' : '单曲循环'">
              <i :class="isLoop ? 'fas fa-repeat fa-fw active' : 'fas fa-repeat fa-fw'"></i>
            </button>
            <button class="icon-btn" @click="toggleList" title="歌曲列表">
              <i class="fas fa-list"></i>
            </button>
          </div>
        </div>
        <div class="music-list-section" :class="{ show: showList }">
          <div class="list-header">
            <span>歌曲列表</span>
            <button class="close-btn" @click="showList = false">
              <i class="fas fa-times"></i>
            </button>
          </div>
          <ul class="music-list">
            <li
              v-for="(song, idx) in songs"
              :key="song.id"
              :class="{ active: idx === currentSongIndex }"
              @click="selectSong(idx)">
              <span>{{ idx + 1 }}. {{ song.name }} - {{ song.artist }}</span>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <audio ref="audioRef" :src="'/api/music/' + currentSong.fileName + '/'"></audio>
  </div>
</template>

<style scoped>
.music-player-box {
  align-items: stretch;
  background: var(--card-bg);
  border-radius: var(--border-radius);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow);
  min-height: 120px;
  position: relative;
  transition: var(--transition);
}

.music-player-box:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow);
  border-color: rgba(var(--primary-rgb), 0.5);
}

.music-player-box.show {
  min-height: 320px;
}

.music-cover {
  height: 110px;
  margin: 20px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #eee;
}
.music-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 8px;
}
.music-info-panel {
  padding: 0 20px;
}

.music-title {
  font-size: 18px;
  font-weight: bold;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.music-artist {
  font-size: 14px;
  color: var(--gray);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.music-info-bottom {
  display: flex;
  flex-direction: column;
}
.progress-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.progress-bar {
  flex: 1;
  height: 4px;
  background: rgb(187 143 14 / 50%);
  border-radius: 2px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
}
.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--primary), var(--secondary));
  border-radius: 2px;
  transition: width 0.1s ease;
}
.time {
  font-size: 12px;
  color: var(--gray);
  width: 40px;
  text-align: center;
}
.controls-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 2px;
}
.icon-btn {
  background: none;
  border: none;
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
  border-radius: 50%;
  transition: background 0.2s, color 0.2s, transform 0.2s;
  position: relative;
}
.icon-btn:hover {
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary);
  transform: scale(1.1);
}
.icon-btn:active {
  background: rgba(var(--primary-rgb), 0.18);
}
.fa-repeat.active {
  color: #00d4aa;
}

.music-list-section {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
  border-top: 1px solid transparent;
  margin-top: 10px;
}

.music-list-section.show {
  max-height: 200px;
  border-top-color: var(--glass-border);
}

.list-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0 6px 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--primary);
}
.close-btn {
  background: none;
  border: none;
  color: var(--gray);
  font-size: 16px;
  cursor: pointer;
  padding: 4px;
  border-radius: 50%;
  transition: background 0.2s, color 0.2s;
}
.close-btn:hover {
  background: rgba(var(--primary-rgb), 0.1);
  color: var(--primary);
}
.music-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 150px;
  overflow-y: auto;
}
.music-list li {
  padding: 7px 0;
  font-size: 14px;
  color: var(--text);
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.2s, color 0.2s;
  display: flex;
  align-items: center;
}
.music-list li.active {
  background: rgba(var(--primary-rgb), 0.12);
  color: var(--primary);
  font-weight: 600;
}
.music-list li:hover {
  background: rgba(var(--primary-rgb), 0.08);
  color: var(--primary);
}

@media (max-width: 1100px) {
  .music-player-box {
    grid-column: span 2;
  }
}
</style>
